// /////////////////////////////////////////////////////////////////////////////
//
// Name:            AIScript.cpp
// Author:          Michael Bartsch
//
// Desc:            This file contains the Glue functions that enable the
//                  interaction between CAICore and Lua.
//
// License:         Copyright (C) 2008-2009 Michael Bartsch
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the GNU General Public
//                  License as published by the Free Software Foundation,
//                  either version 3 of the License, or (at your option) any
//                  later version.
//
//                  This program is distributed in the hope that it will be
//                  useful, but WITHOUT ANY WARRANTY; without even the implied
//                  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//                  PURPOSE. See the GNU General Public License for more
//                  details.
//
//                  You should have received a copy of the GNU General Public
//                  License along with this program. If not, see
//                  <http://www.gnu.org/licenses/>.
//
// /////////////////////////////////////////////////////////////////////////////

// Include required header file(s).
#include "AIScript.h"


// Registers CCommunicator.
void registerAI(lua_State *L)
{
    // Register low level functions.
    lua_register(L, "aiUpdate",            lua_ai_update);

    lua_register(L, "aiCalculatePath",     lua_ai_calculatePath);
    lua_register(L, "aiCheckEnvironment",  lua_ai_checkEnvironment);

    lua_register(L, "aiGetStartX",         lua_ai_getStartX);
    lua_register(L, "aiGetStartY",         lua_ai_getStartY);
    lua_register(L, "aiGetTargetX",        lua_ai_getTargetX);
    lua_register(L, "aiGetTargetY",        lua_ai_getTargetY);
    lua_register(L, "aiGetNextX",          lua_ai_getNextX);
    lua_register(L, "aiGetNextY",          lua_ai_getNextY);

    lua_register(L, "aiGetRotation",       lua_ai_getRotation);
    lua_register(L, "aiGetIsTarget",       lua_ai_getIsTarget);
    lua_register(L, "aiGetAgentState",     lua_ai_getAgentState);
    lua_register(L, "aiGetIsWaiting",      lua_ai_getIsWaiting);

    lua_register(L, "aiSetStartLocation",  lua_ai_setStartLocation);
    lua_register(L, "aiSetStartX",         lua_ai_setStartX);
    lua_register(L, "aiSetStartY",         lua_ai_setStartY);

    lua_register(L, "aiSetTargetLocation", lua_ai_setTargetLocation);
    lua_register(L, "aiSetTargetX",        lua_ai_setTargetX);
    lua_register(L, "aiSetTargetY",        lua_ai_setTargetY);

    lua_register(L, "aiSetRotation",       lua_ai_setRotation);
    lua_register(L, "aiSetNodeState",      lua_ai_setNodeState);
    lua_register(L, "aiSetIsTarget",       lua_ai_setIsTarget);
    lua_register(L, "aiSetAgentState",     lua_ai_setAgentState);
    lua_register(L, "aiResetMap",          lua_ai_resetMap);
    lua_register(L, "aiSetIsWaiting",      lua_ai_setIsWaiting);

    // Register the CCommunicator class.
    char buffer[] =
    {
       "CAICore = {}\n" \
       "CAICore.__index = CAICore\n" \
       "\n" \
       "function CAICore.create()\n" \
       "   local handle = {}\n" \
       "   setmetatable(handle, CAICore)\n" \
       "   return handle\n" \
       "end\n" \
       "\n" \
       "function CAICore:update() aiUpdate() end\n" \
       "\n" \
       "function CAICore:calculatePath() aiCalculatePath() end\n" \
       "function CAICore:checkEnvironment() aiCheckEnvironment() end\n" \
       "\n" \
       "function CAICore:getStartX() return aiGetStartX() end\n" \
       "function CAICore:getStartY() return aiGetStartY() end\n" \
       "function CAICore:getTargetX() return aiGetTargetX() end\n" \
       "function CAICore:getTargetY() return aiGetTargetY() end\n" \
       "function CAICore:getNextX() return aiGetNextX() end\n" \
       "function CAICore:getNextY() return aiGetNextY() end\n" \
       "\n" \
       "function CAICore:getRotation() return aiGetRotation() end\n" \
       "function CAICore:getIsTarget() return aiGetIsTarget() end\n" \
       "function CAICore:getAgentState() return aiGetAgentState() end\n" \
       "function CAICore:getIsWaiting() return aiGetIsWaiting() end\n" \
       "\n" \
       "function CAICore:setStartLocation(x, y) return aiSetStartLocation(x, y) end\n" \
       "function CAICore:setStartX(value) return aiSetStartX(value) end\n" \
       "function CAICore:setStartY(value) return aiSetStartY(value) end\n" \
       "\n" \
       "function CAICore:setTargetLocation(x, y) return aiSetTargetLocation(x, y) end\n" \
       "function CAICore:setTargetX(value) return aiSetTargetX(value) end\n" \
       "function CAICore:setTargetY(value) return aiSetTargetY(value) end\n" \
       "\n" \
       "function CAICore:setRotation(value) return aiRotation(value) end\n" \
       "function CAICore:setNodeState(x, y, state) return aiSetNodeState(x, y, state) end\n" \
       "function CAICore:setIsTarget(value) return aiSetIsTarget(value) end\n" \
       "function CAICore:setAgentState(value) return aiSetAgentState(value) end\n" \
       "function CAICore:setIsWaiting(value) return aiSetIsWaiting(value) end\n" \
       "function CAICore:resetMap() resetMap() end\n" \
       "\n" \
       "AICore = CAICore.create()"
    };

    luaL_dostring(L, buffer);
}

// Glue functions:
// Glue function for CAICore::update.
int lua_ai_update(lua_State *L)
{
   CAICore::Instance()->update();
   return 0;
}

// Glue function for CAICore::calculatePath.
int lua_ai_calculatePath(lua_State *L)
{
   CAICore::Instance()->calculatePath();
   return 0;
}
// Glue function for CAICore::checkEnvironment.
int lua_ai_checkEnvironment(lua_State *L)
{
   CAICore::Instance()->checkEnvironment();
   return 0;
}

// Glue function for CAICore::getStartX.
int lua_ai_getStartX(lua_State *L)
{
   lua_pushnumber(L, CAICore::Instance()->getStartX());
   return 1;
}
// Glue function for CAICore::getStartY.
int lua_ai_getStartY(lua_State *L)
{
   lua_pushnumber(L, CAICore::Instance()->getStartY());
   return 1;
}
// Glue function for CAICore::getTargetX.
int lua_ai_getTargetX(lua_State *L)
{
   lua_pushnumber(L, CAICore::Instance()->getTargetX());
   return 1;
}
// Glue function for CAICore::getTargetY.
int lua_ai_getTargetY(lua_State *L)
{
   lua_pushnumber(L, CAICore::Instance()->getTargetY());
   return 1;
}
// Glue function for CAICore::getNextX.
int lua_ai_getNextX(lua_State *L)
{
   lua_pushnumber(L, CAICore::Instance()->getNextX());
   return 1;
}
// Glue function for CAICore::getNextY.
int lua_ai_getNextY(lua_State *L)
{
   lua_pushnumber(L, CAICore::Instance()->getNextY());
   return 1;
}

// Glue function for CAICore::getRotation.
int lua_ai_getRotation(lua_State *L)
{
   lua_pushnumber(L, CAICore::Instance()->getRotation());
   return 1;
}

// Glue function for CAICore::getIsTarget
int lua_ai_getIsTarget(lua_State *L)
{
   lua_pushboolean(L, CAICore::Instance()->getIsTarget());
   return 1;
}

// Glue function for CAICore::getAgentState.
int lua_ai_getAgentState(lua_State *L)
{
   lua_pushnumber(L, CAICore::Instance()->getAgentState());
   return 1;
}

// Glue function for CAICore::getIsWaiting
int lua_ai_getIsWaiting(lua_State *L)
{
   lua_pushboolean(L, CAICore::Instance()->getIsWaiting());
   return 1;
}

// Glue function for CAICore::setStartLocation.
int lua_ai_setStartLocation(lua_State *L)
{
   int x, y;
   int lua_argnum = lua_gettop(L);

   if(lua_argnum >= 1)   x = (int)lua_tonumber(L, 1);
   if(lua_argnum >= 2)   y = (int)lua_tonumber(L, 2);

   CAICore::Instance()->setStartLocation(x, y);

   return 0;
}
// Glue function for CAICore::setStartX.
int lua_ai_setStartX(lua_State *L)
{
   int lua_var;
   int lua_argnum = lua_gettop(L);

   if(lua_argnum >= 1)   lua_var = (int)lua_tonumber(L, 1);

   CAICore::Instance()->setStartX(lua_var);

   return 0;
}
// Glue function for CAICore::setStartY.
int lua_ai_setStartY(lua_State *L)
{
   int lua_var;
   int lua_argnum = lua_gettop(L);

   if(lua_argnum >= 1)   lua_var = (int)lua_tonumber(L, 1);

   CAICore::Instance()->setStartY(lua_var);

   return 0;
}

// Glue function for CAICore::setTargetLocation.
int lua_ai_setTargetLocation(lua_State *L)
{
   int x, y;
   int lua_argnum = lua_gettop(L);

   if(lua_argnum >= 1)   x = (int)lua_tonumber(L, 1);
   if(lua_argnum >= 2)   y = (int)lua_tonumber(L, 2);

   CAICore::Instance()->setTargetLocation(x, y);

   return 0;
}
// Glue function for CAICore::setTargetX
int lua_ai_setTargetX(lua_State *L)
{
   int lua_var;
   int lua_argnum = lua_gettop(L);

   if(lua_argnum >= 1)   lua_var = (int)lua_tonumber(L, 1);

   CAICore::Instance()->setTargetX(lua_var);

   return 0;
}
// Glue function for CAICore::setTargetY.
int lua_ai_setTargetY(lua_State *L)
{
   int lua_var;
   int lua_argnum = lua_gettop(L);

   if(lua_argnum >= 1)   lua_var = (int)lua_tonumber(L, 1);

   CAICore::Instance()->setTargetY(lua_var);

   return 0;
}

// Glue function for CAICore::setRotation
int lua_ai_setRotation(lua_State *L)
{
   int lua_var;
   int lua_argnum = lua_gettop(L);

   if(lua_argnum >= 1)   lua_var = (int)lua_tonumber(L, 1);

   CAICore::Instance()->setRotation(lua_var);

   return 0;
}

// Glue function for CAICore::setNodeState
int lua_ai_setNodeState(lua_State *L)
{
   int x, y, state;
   int lua_argnum = lua_gettop(L);

   if(lua_argnum >= 1)   x = (int)lua_tonumber(L, 1);
   if(lua_argnum >= 2)   y = (int)lua_tonumber(L, 2);
   if(lua_argnum >= 3)   state = (int)lua_tonumber(L, 3);

   CAICore::Instance()->setNodeState(x, y, (AStarNodeStates)state);

   return 0;
}

// Glue function for CAICore::setIsTarget
int lua_ai_setIsTarget(lua_State *L)
{
   bool lua_var;
   int lua_argnum = lua_gettop(L);

   if(lua_argnum >= 1)   lua_var = (bool)lua_toboolean(L, 1);

   CAICore::Instance()->setIsTarget(lua_var);

   return 0;
}

// Glue function for CAICore::setAgentState
int lua_ai_setAgentState(lua_State *L)
{
   int lua_var;
   int lua_argnum = lua_gettop(L);

   if(lua_argnum >= 1)   lua_var = (int)lua_tonumber(L, 1);

   CAICore::Instance()->setAgentState(lua_var);

   return 0;
}

// Glue function for CAICore::setIsWaiting
int lua_ai_setIsWaiting(lua_State *L)
{
   bool lua_var;
   int lua_argnum = lua_gettop(L);

   if(lua_argnum >= 1)   lua_var = (bool)lua_toboolean(L, 1);

   CAICore::Instance()->setIsWaiting(lua_var);

   return 0;
}

// Glue function for CAICore::resetMap
int lua_ai_resetMap(lua_State *L)
{
   CAICore::Instance()->resetMap();
   return 0;
}
// End of File.
